﻿using System;
using System.Drawing.Design;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using EnvDTE;
using Microsoft.Practices.ComponentModel;
using System.Collections.Specialized;
using SMC.SPALM.Types;

namespace SteriaMummert.SharePoint.SoftwareFactoryLite.Editors
{
    [ServiceDependency(typeof(DTE))]
    public class BaseSharePointConfigurationEditor : UITypeEditor
    {
        protected SharePointConfigurationStyle style = SharePointConfigurationStyle.TreeView;
        protected string internalGroup = "";
        protected string internalXPath = "";
        protected string internalNamespace = "";
        protected string internalID = "";
        protected string internalName = "";

        protected string externalXPath = "";
        protected NameValueCollection externalNamespace = new NameValueCollection();
        protected string externalID = "";
        protected string externalName = "";
        protected string externalGroupBy = "";

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }

        private void NavigateProjectItems(ProjectItems projectitems, NameValueCollection fields)
        {
            if (projectitems != null)
            {
                foreach (ProjectItem item in projectitems)
                {
                    if (item.Name.EndsWith(".xml"))
                    {
                        try
                        {
                            string path = item.Properties.Item("FullPath").Value.ToString();
                            XmlDocument doc = new XmlDocument();
                            doc.Load(path);
                            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                            nsmgr.AddNamespace("ns", internalNamespace);
                            foreach (XmlNode node in doc.SelectNodes(internalXPath, nsmgr))
                            {
                                //is item already in the list?
                                if (fields[node.Attributes[internalID].Value] == null)
                                {
                                    fields.Add(node.Attributes[internalID].Value, node.Attributes[internalName].Value);
                                }
                            }
                        }
                        catch (Exception ex)
                        {                            
                        }
                    }
                    if(item.ProjectItems != null)
                    {
                        if (item.ProjectItems.Count > 0)
                        {
                            NavigateProjectItems(item.ProjectItems, fields);
                        }
                    }
                }
            }
        }

        private NameValueCollection GetInternalItems(DTE dte)
        {
            NameValueCollection fields = new NameValueCollection();
            try
            {
                foreach (Project project in dte.Solution.Projects)
                {
                    NavigateProjectItems(project.ProjectItems, fields);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            return fields;
        }

        private void AddInternalItems(DTE dte, TreeView treeview)
        {
            NameValueCollection fields = GetInternalItems(dte);
            if (fields.Count > 0)
            {
                TreeNode internode = treeview.Nodes.Add(internalGroup);
                foreach (string key in fields.Keys)
                {
                    TreeNode intersubnode = internode.Nodes.Add(fields[key]);
                    intersubnode.Tag = key;
                }
            }
        }

        private XmlDocument GetSharePointConfigFile(DTE dte)
        {
            //Path to the solution directory
            string solutionDirectory = Path.GetDirectoryName((string)dte.Solution.Properties.Item("Path").Value);
            string toPath = Path.Combine(solutionDirectory, "SharepointConfiguration.xml");

            XmlDocument doc = new XmlDocument();

            if (File.Exists(toPath))
            {

                doc.Load(toPath);
            }
            return doc;
        }

        private void AddExternalItems(DTE dte, TreeView treeview)
        {
            try
            {
                XmlDocument doc = GetSharePointConfigFile(dte);

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                foreach (string s in externalNamespace)
                {
                    nsmgr.AddNamespace(s, externalNamespace[s]);
                }

                foreach (XmlNode node in doc.SelectNodes(externalXPath, nsmgr))
                {
                    if (node.Attributes[externalGroupBy] != null)
                    {
                        string val = node.Attributes[externalGroupBy].Value;
                        if (!treeview.Nodes.ContainsKey(val))
                        {
                            TreeNode node1 = treeview.Nodes.Add(val, val);

                            foreach (XmlNode subnode in doc.SelectNodes(externalXPath + "[@" + externalGroupBy + "='" + val + "']", nsmgr))
                            {
                                TreeNode node2 = node1.Nodes.Add(subnode.Attributes[externalID].Value, subnode.Attributes[externalName].Value);
                                node2.Tag = subnode.Attributes[externalID].Value;
                            }
                        }
                    }
                }
               
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public override object EditValue(ITypeDescriptorContext context,
            IServiceProvider provider, object value)
        {
            TreeView treeview = new TreeView();
            DTE dte = (DTE)provider.GetService(typeof(DTE));

            if (style == SharePointConfigurationStyle.TreeView)
            {
                AddInternalItems(dte, treeview);

                AddExternalItems(dte, treeview);

                IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                treeview.AfterSelect += delegate(object sender, TreeViewEventArgs e)
                {
                    if (e.Action != TreeViewAction.Unknown)
                    {
                        editorService.CloseDropDown();
                    }
                };
                editorService.DropDownControl(treeview);

                if (treeview.SelectedNode != null)
                {
                    if (treeview.SelectedNode.Tag != null)
                    {
                        if (this.style == SharePointConfigurationStyle.FlatList)
                        {
                            return treeview.SelectedNode.Tag;
                        }
                        return new NameValueItem(treeview.SelectedNode.Tag.ToString(), treeview.SelectedNode.Text); //treeview.SelectedNode.Tag;
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }
            else
            {
                ListBox box = new ListBox();
                box.Sorted = true;

                try
                {
                    NameValueCollection fields = GetInternalItems(dte);
                    if (fields.Count > 0)
                    {
                        foreach (string key in fields.Keys)
                        {
                            box.Items.Add(new NameValueItem(key, fields[key]));
                        }
                    }

                    NameValueCollection collection = new NameValueCollection();
                    AddExternalItems(dte, collection);
                    foreach (string key in collection.Keys)
                    {
                        box.Items.Add(new NameValueItem(key, collection[key]));
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

                IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                box.SelectedIndexChanged += delegate(object sender, EventArgs e)
                {
                    editorService.CloseDropDown();
                };
                editorService.DropDownControl(box);

                
                if (box.SelectedItem != null)
                {
                    if (this.style == SharePointConfigurationStyle.FlatList)
                    {
                        return ((NameValueItem)box.SelectedItem).ID;
                    }

                    return box.SelectedItem; // new NameValueItem(box.SelectedItem.ToString(), box.SelectedItem.ToString());
                }
                else
                {
                    return null;
                }
            }
        }

        
        private void AddExternalItems(DTE dte, NameValueCollection collection)
        {
            XmlDocument doc = GetSharePointConfigFile(dte);

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            foreach (string s in externalNamespace)
            {
                nsmgr.AddNamespace(s, externalNamespace[s]);
            }

            foreach (XmlNode node in doc.SelectNodes(externalXPath, nsmgr))
            {
                if ((node.Attributes[externalID] != null) && (node.Attributes[externalName] != null))
                {
                    if (collection[node.Attributes[externalID].Value] == null)
                    {
                        collection.Add(node.Attributes[externalID].Value, node.Attributes[externalName].Value);
                    }
                }
            }
        }        

        public override bool IsDropDownResizable
        {
            get
            {
                return true;
            }
        }
    }

    public enum SharePointConfigurationStyle
    {
        List = 1,
        TreeView = 2,
        FlatList = 3
    }    
}
